#include <QyDebug.h>
#include <QyRenderLayer.h>
#include <QyTexturePool.h>
#include "QpwRenderItems.h"

using namespace QpwItems;

/**************************************************************************************************/

inline QPointF operator / ( const QPointF & p1, const QPointF & p2 ) {

    return QPointF( p1.x() / p2.x(), p1.y() / p2.y() );
}

/**************************************************************************************************/

Decoration::Decoration( QyRender::Layer * layer ) : Item(layer), p_texture(0) {

    p_color = QColor(Qt::black);

}

Decoration::~Decoration() {
}

QPointF Decoration::pos() const {

    return boundingRect().center();
}

void Decoration::paint( const PaintMode & mode ) {

    switch (mode) {

    case DefaultPaint:

        if ( p_animations.contains(p_currentAnimation) ) {

            if ( QyGL::Texture * texture = p_animations[p_currentAnimation].currentTexture() )
                texture->bind();

        } else if (p_texture) {

            p_texture->bind();

        }

        if ( p_color.isValid() ) {

            glColor3d( p_color.redF(), p_color.greenF(), p_color.blueF() );

        }

        break;

    case BasicPaint:
        break;

    }

    if ( p_textureCoords.isEmpty() )
        p_textureCoords = buildTextureCoords();

    int i,
        count = p_geometry.count();
    bool textured = p_textureCoords.count() == count && mode == DefaultPaint;
    QPointF pos;

//     QyDbgValue( position.toPointF() );
//     QyDbgValue( count );
//     QyDbgValue( rotation );

    glPushMatrix();
    glTranslated( position.p[0], position.p[1], position.p[2] );
    glRotated( rotation, 0, 0, 1 );
    glBegin(GL_POLYGON);
    for ( i = 0; i < count; ++i ) {

        if (textured) {

            pos = p_textureCoords[i];
            glTexCoord2d( pos.x(), pos.y() );

        }

        pos = p_geometry[i];
        glVertex3d( pos.x(), pos.y(), 0 );

    }
    glEnd();
//     glPointSize(5);
//     glColor3d( 1, 0, 0 );
//     glBegin(GL_POINTS);
//     glVertex3d( 0, 0, 0 );
//     glEnd();
//     glPointSize(1);
    glPopMatrix();

}

void Decoration::move( const QPointF & pos ) {

    QPointF currentPos = Decoration::pos();
    QPointF offset = currentPos - pos;
    int i, count = p_geometry.count();

    for ( i = 0; i< count; ++i )
        p_geometry[i] += offset;

}

void Decoration::setSubType( const QpwSubType & subType ) {

    if ( layer() )
        position.p[2] = layer()->z();

}

void Decoration::setStyle( const QpwStyle & style ) {

    p_color = style.color;

    if ( style.texture.count() )
        setTexture(QyTexturePool::staticPool()->textures[style.texture]);

//     QyDbgValue("\n\n  " + QStringList( QyTexturePool::staticPool()->textures.keys() ).join("\n  ") + "\n\n" );
//     QyDbgValue(style.name);
//     QyDbgValue(style.texture);
//     QyDbgValue( style.color.name() );
//     QyDbgValue(style.uuid.toString());
//     QyDbgValue(p_texture);

}

void Decoration::setGeometry( const QpwWorld::Geometry & geometry ) {

    QyRender::ItemGeometry itemGeometry;

    foreach ( QPointF point, geometry )
        itemGeometry.append(point);

    p_geometry = itemGeometry;
    p_textureCoords = buildTextureCoords();

}

QPolygonF Decoration::buildTextureCoords() const {

    int i, count = p_geometry.count();
    QPolygonF textCoords(count);
    QRectF br = boundingRect();
    QPointF currentPos = br.bottomLeft();
    QPointF offset( br.width(), br.height() );

//     QyDbgValue(offset);
//     QyDbgValue(currentPos);

    for ( i = 0; i< count; ++i ) {

        textCoords[i] = ( p_geometry[i] - currentPos ) / offset;
//         QyDbgValue(p_geometry[i]);
//         QyDbgValue(textCoords[i]);

    }

    return textCoords;
}
